import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import * as crypto from 'crypto';

/**
 * 微信服务
 * 基于 NestJS 官方示例实现
 * 参考: https://docs.nestjs.cn/fundamentals/dependency-injection
 * 对应 Java: WechatUtils
 */
@Injectable()
export class WechatService {
  constructor(private readonly configService: ConfigService) {}

  /**
   * 验证微信签名
   */
  verifySignature(
    signature: string,
    timestamp: string,
    nonce: string,
    token: string,
  ): boolean {
    const tmpArr = [token, timestamp, nonce].sort();
    const tmpStr = tmpArr.join('');
    const hash = crypto.createHash('sha1').update(tmpStr).digest('hex');
    return hash === signature;
  }

  /**
   * 生成微信签名
   */
  generateSignature(params: Record<string, any>, key: string): string {
    // 按参数名排序
    const sortedParams = Object.keys(params)
      .sort()
      .map((key) => `${key}=${params[key]}`)
      .join('&');

    const stringSignTemp = `${sortedParams}&key=${key}`;
    return crypto
      .createHash('md5')
      .update(stringSignTemp)
      .digest('hex')
      .toUpperCase();
  }

  /**
   * 生成随机字符串
   */
  generateNonceStr(length: number = 32): string {
    const chars =
      'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let result = '';
    for (let i = 0; i < length; i++) {
      result += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    return result;
  }

  /**
   * 生成时间戳
   */
  generateTimestamp(): string {
    return Math.floor(Date.now() / 1000).toString();
  }

  /**
   * 生成微信支付签名
   */
  generatePaySignature(params: Record<string, any>, key: string): string {
    // 过滤空值
    const filteredParams = Object.keys(params)
      .filter(
        (key) =>
          params[key] !== '' &&
          params[key] !== null &&
          params[key] !== undefined,
      )
      .reduce(
        (obj, key) => {
          obj[key] = params[key];
          return obj;
        },
        {} as Record<string, any>,
      );

    // 按参数名排序
    const sortedParams = Object.keys(filteredParams)
      .sort()
      .map((key) => `${key}=${filteredParams[key]}`)
      .join('&');

    const stringSignTemp = `${sortedParams}&key=${key}`;
    return crypto
      .createHash('md5')
      .update(stringSignTemp)
      .digest('hex')
      .toUpperCase();
  }

  /**
   * 验证微信支付签名
   */
  verifyPaySignature(
    params: Record<string, any>,
    signature: string,
    key: string,
  ): boolean {
    const expectedSignature = this.generatePaySignature(params, key);
    return expectedSignature === signature;
  }

  /**
   * 生成微信JSAPI签名
   */
  generateJSAPISignature(params: Record<string, any>, key: string): string {
    const sortedParams = Object.keys(params)
      .sort()
      .map((key) => `${key}=${params[key]}`)
      .join('&');

    return crypto.createHash('sha1').update(sortedParams).digest('hex');
  }

  /**
   * 生成微信小程序签名
   */
  generateMiniProgramSignature(
    params: Record<string, any>,
    key: string,
  ): string {
    return this.generatePaySignature(params, key);
  }

  /**
   * 生成微信H5签名
   */
  generateH5Signature(params: Record<string, any>, key: string): string {
    return this.generatePaySignature(params, key);
  }

  /**
   * 生成微信APP签名
   */
  generateAPPSignature(params: Record<string, any>, key: string): string {
    return this.generatePaySignature(params, key);
  }

  /**
   * 生成微信Native签名
   */
  generateNativeSignature(params: Record<string, any>, key: string): string {
    return this.generatePaySignature(params, key);
  }

  /**
   * 生成微信扫码签名
   */
  generateScanSignature(params: Record<string, any>, key: string): string {
    return this.generatePaySignature(params, key);
  }

  /**
   * 生成微信刷卡签名
   */
  generateMicropaySignature(params: Record<string, any>, key: string): string {
    return this.generatePaySignature(params, key);
  }

  /**
   * 生成微信退款签名
   */
  generateRefundSignature(params: Record<string, any>, key: string): string {
    return this.generatePaySignature(params, key);
  }

  /**
   * 生成微信查询签名
   */
  generateQuerySignature(params: Record<string, any>, key: string): string {
    return this.generatePaySignature(params, key);
  }

  /**
   * 生成微信关闭订单签名
   */
  generateCloseSignature(params: Record<string, any>, key: string): string {
    return this.generatePaySignature(params, key);
  }

  /**
   * 生成微信撤销签名
   */
  generateReverseSignature(params: Record<string, any>, key: string): string {
    return this.generatePaySignature(params, key);
  }

  /**
   * 生成微信转换短链接签名
   */
  generateShortUrlSignature(params: Record<string, any>, key: string): string {
    return this.generatePaySignature(params, key);
  }

  /**
   * 生成微信转换长链接签名
   */
  generateLongUrlSignature(params: Record<string, any>, key: string): string {
    return this.generatePaySignature(params, key);
  }

  /**
   * 生成微信下载对账单签名
   */
  generateDownloadBillSignature(
    params: Record<string, any>,
    key: string,
  ): string {
    return this.generatePaySignature(params, key);
  }

  /**
   * 生成微信拉取订单评价数据签名
   */
  generateBatchQueryCommentSignature(
    params: Record<string, any>,
    key: string,
  ): string {
    return this.generatePaySignature(params, key);
  }
}
